package com.hmdp;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 分段锁来管理库存
 */
public class InventoryManager {
    // 假设总库存为100
    private static final int TOTAL_INVENTORY = 100;
    // 分为10个片段
    private static final int SEGMENT_COUNT = 10;
    // 每个片段的库存数量
    private static final int SEGMENT_SIZE = TOTAL_INVENTORY / SEGMENT_COUNT;
    // 存储每个片段的锁
    private final Lock[] segmentLocks = new ReentrantLock[SEGMENT_COUNT];
    // 存储每个片段的库存
    private final int[] segmentInventory = new int[SEGMENT_COUNT];

    public InventoryManager() {
        for (int i = 0; i < SEGMENT_COUNT; i++) {
            segmentLocks[i] = new ReentrantLock();
            segmentInventory[i] = SEGMENT_SIZE;
        }
    }

    // 购买商品的方法
    public boolean purchaseItem(int quantity) {
        for (int i = 0; i < SEGMENT_COUNT; i++) {
            // 获取对应的锁
            Lock lock = segmentLocks[i];
            lock.lock();
            try {
                // 检查当前片段是否有足够的库存
                if (segmentInventory[i] >= quantity) {
                    // 减少库存
                    segmentInventory[i] -= quantity;
                    return true;
                }
            } finally {
                // 释放锁
                lock.unlock();
            }
        }
        // 所有片段都没有足够的库存
        return false;
    }

    // 获取当前总库存
    public int getCurrentInventory() {
        int total = 0;
        for (int i = 0; i < SEGMENT_COUNT; i++) {
            segmentLocks[i].lock();
            try {
                total += segmentInventory[i];
            } finally {
                segmentLocks[i].unlock();
            }
        }
        return total;
    }

    public static void main(String[] args) {
        InventoryManager manager = new InventoryManager();

        // 模拟多个线程同时购买商品
        for (int i = 0; i < 20; i++) {
            int finalI = i;
            new Thread(() -> {
                if (manager.purchaseItem(1)) {
                    System.out.println("线程" + finalI + "购买成功");
                } else {
                    System.out.println("线程" + finalI + "购买失败");
                }
            }).start();
        }
    }
}
